package rename_tab

import (
	"file_explorer/common/log"
	"file_explorer/model"
	"file_explorer/service"
	"file_explorer/service/eventbus"
	"file_explorer/view/components/main_panel/rename_tab/rule_window"
	"file_explorer/view/packed_widgets"
	"file_explorer/view/store"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"github.com/samber/lo"
)

type RenameRuleList struct {
	*fyne.Container

	toolbar   *widget.Toolbar
	ruleTable *packed_widgets.Table

	tabCtx *store.RenameTabContext
}

func (ruleList *RenameRuleList) onRuleOrderChanged() {
	ruleList.ruleTable.Refresh()
	ruleList.tabCtx.ExecuteRules()
}

func (ruleList *RenameRuleList) onRuleItemChanged() {
	ruleList.ruleTable.Reset()
	ruleList.tabCtx.ExecuteRules()
}

// 从context回写CheckList状态
func (ruleList *RenameRuleList) reloadCheckList() {
	checkItemSet := make(map[*model.ModifiedFileInfo]struct{})
	for _, checkItem := range ruleList.tabCtx.CheckedFiles {
		checkItemSet[checkItem] = struct{}{}
	}
	checkIndexList := make([]int, 0, len(checkItemSet))
	for i, fileInfo := range ruleList.tabCtx.FileInfos {
		if _, ok := checkItemSet[fileInfo]; ok {
			checkIndexList = append(checkIndexList, i)
		}
	}
	ruleList.ruleTable.Checklist.SetCheckIndexList(checkIndexList)
}

func (ruleList *RenameRuleList) buildToolbar() {
	// 规则列表工具栏 新增 按钮，创建规则窗口
	addButton := packed_widgets.NewButton("新增", theme.ContentAddIcon(), func() {
		rule_window.NewRuleWindow(ruleList.tabCtx, func() {
			ruleList.onRuleItemChanged()
		})
	})

	// 规则列表工具栏 移除 按钮，移除选中规则
	deleteButton := packed_widgets.NewButton("移除", theme.ContentRemoveIcon(), func() {
		checkedRuleSet := make(map[model.RenameRule]struct{})
		for _, checkedRule := range ruleList.tabCtx.CheckedRules {
			checkedRuleSet[checkedRule] = struct{}{}
		}

		newRules := make([]model.RenameRule, 0, len(ruleList.tabCtx.Rules))
		for _, rule := range ruleList.tabCtx.Rules {
			if _, ok := checkedRuleSet[rule]; !ok {
				newRules = append(newRules, rule)
			}
		}
		ruleList.tabCtx.CheckedRules = nil
		ruleList.tabCtx.Rules = newRules
		ruleList.onRuleItemChanged()
		log.Info("重命名页移除规则%d项", len(checkedRuleSet))
	})

	deleteButton.Disable()

	ruleList.ruleTable.Checklist.RegisterConsumer(eventbus.EventKeyWidgetChecklistChange, func(event *model.Event) {
		log.Info("重命名页选中规则变更")
		if ruleList.ruleTable.Checklist.GetCheckNum() > 0 {
			deleteButton.Enable()
			return
		}
		deleteButton.Disable()
	})

	// 保存规则按钮
	storeButton := packed_widgets.NewButton("保存", theme.DocumentSaveIcon(), func() {
		nameEntry := widget.NewEntry()
		dialog.ShowForm("保存规则", "确认", "取消",
			[]*widget.FormItem{
				widget.NewFormItem("名称", nameEntry),
			},
			func(confirm bool) {
				if !confirm || len(nameEntry.Text) == 0 || len(ruleList.tabCtx.Rules) == 0 {
					return
				}
				err := service.WriteRenameRuleConf(nameEntry.Text, ruleList.tabCtx.Rules)
				if err != nil {
					packed_widgets.NotifyError("保存重命名规则失败")
					return
				}
				log.Info("保存重命名规则成功")
			},
			packed_widgets.GetAppWindow())
	})

	// 载入规则按钮
	loadButton := packed_widgets.NewMenuButton("载入", theme.HistoryIcon())
	for _, conf := range service.ReadRenameRuleConfs() {
		loadButton.AddItem(conf.Key, conf, func(data interface{}) {
			ruleList.tabCtx.Rules = data.(*model.RenameRuleConf).Rules
			ruleList.tabCtx.CheckedRules = nil
			ruleList.onRuleItemChanged()
			log.Info("载入重命名规则成功")
		})
	}

	getData := func() []interface{} {
		return lo.Map(ruleList.tabCtx.Rules, func(item model.RenameRule, index int) interface{} {
			return item
		})
	}
	updateCtx := func(interfaces []interface{}) {
		ruleList.tabCtx.Rules = lo.Map(interfaces, func(item interface{}, index int) model.RenameRule {
			return item.(model.RenameRule)
		})
		ruleList.onRuleOrderChanged()
	}

	ruleList.toolbar = widget.NewToolbar(
		ruleList.ruleTable.Checklist.GetMoveUpButton(getData, updateCtx),
		ruleList.ruleTable.Checklist.GetMoveDownButton(getData, updateCtx),
		ruleList.ruleTable.Checklist.GetMoveTopButton(getData, updateCtx),
		ruleList.ruleTable.Checklist.GetMoveBottomButton(getData, updateCtx),
		widget.NewToolbarSpacer(),
		storeButton,
		loadButton,
		widget.NewToolbarSpacer(),
		addButton,
		deleteButton,
	)

}

func (ruleList *RenameRuleList) buildRuleTable() {
	ruleList.ruleTable = packed_widgets.NewTable()
	ruleList.ruleTable.SetGetData(func(index int) interface{} {
		return ruleList.tabCtx.Rules[index]
	})
	ruleList.ruleTable.SetGetDataLength(func() int {
		return len(ruleList.tabCtx.Rules)
	})
	ruleList.ruleTable.AddColumn(
		packed_widgets.NewTableColumn().
			SetHeader("规则").
			SetWidth(500).
			SetTextGetter(func(data interface{}) string { return data.(model.RenameRule).GetDescription() }),
	)

	ruleList.ruleTable.Build()
}

func newRenameRuleList(tabCtx *store.RenameTabContext) *RenameRuleList {
	ruleList := &RenameRuleList{
		tabCtx: tabCtx,
	}

	ruleList.buildRuleTable()
	ruleList.buildToolbar()

	ruleList.Container = container.NewBorder(
		ruleList.toolbar,
		nil,
		nil,
		nil,
		container.NewScroll(ruleList.ruleTable.Table),
	)

	return ruleList
}
